<script setup lang="ts">
import { onMounted, onUnmounted, ref, shallowRef, watch } from 'vue'
import { init as initEChart, type ECharts, type SeriesOption, type EChartsOption } from 'echarts'
import {
  SpeedTypeSelect,
  SpeedUnitSelect,
  LengthUnitSelect,
  SpeedType,
  SpeedUnit,
  LengthUnit,
  fromMeterConverter,
  fromMpsConvert,
  speedUnitName,
  lengthUnitName
} from '@/widgets'
import {
  calcClimbFlightEnvelopeById,
  type FlightEnvelope,
  type FlightEnvelopeItem
} from './flight-envelope'
import { calcClimbAirlineProcedureById, type ProcedureProfile } from './airline-procedure'
import BADAAircraftTypeSelect from './BADAAircraftTypeSelect.vue'

const acType = ref<string>('A320')
const spdType = shallowRef<SpeedType>(SpeedType.TAS)
const spdUnit = shallowRef<SpeedUnit>(SpeedUnit.KT)
const altUnit = shallowRef<LengthUnit>(LengthUnit.FT)

let flightEnvelope: FlightEnvelope
function updateFlightEnvelope() {
  flightEnvelope = calcClimbFlightEnvelopeById(acType.value)
}
let stdProcedure: ProcedureProfile
function updateStdProcedure() {
  stdProcedure = calcClimbAirlineProcedureById(acType.value)
}

const chartEl = ref<HTMLDivElement>()
let chart: ECharts | null = null

function updateChart() {
  if (!chart) {
    return
  }
  const opt: EChartsOption = {
    title: {
      left: 'right',
      text: `${acType.value}爬升飞行包线(ISA)`,
      subtext: makeSubTitle()
    },
    backgroundColor: '#fff',
    legend: {},
    tooltip: {
      axisPointer: { type: 'cross' }
    },
    xAxis: {
      name: getXName(),
      type: 'value'
    },
    yAxis: {
      name: `高度(${lengthUnitName(altUnit.value)})`,
      type: 'value'
    },
    series: makeSeries()
  }
  chart.clear()
  chart.setOption(opt)
}

function makeSubTitle(): string {
  const fnv = flightEnvelope
  const prod = stdProcedure.procedure
  return (
    `minCAS:${fnv.minKCAS.to.toFixed(0)}/${fnv.minKCAS.ic.toFixed(0)}/${fnv.minKCAS.cr.toFixed(
      0
    )}kt\n` +
    `maxAlt: ${fnv.maxAltFt.toFixed(0)}ft\n` +
    `maxCAS: ${fnv.maxKCAS.toFixed(0)}kt\n` +
    `maxMach: ${fnv.maxM.toFixed(2)}\n` +
    `${prod.vCl1.toFixed(0)}kt/${prod.vCl2.toFixed(0)}kt/M${Math.round(prod.mCl * 100)}`
  )
}

function getXName(): string {
  if (spdType.value === SpeedType.Mach) {
    return 'ma'
  }
  return spdType.value + '(' + speedUnitName(spdUnit.value) + ')'
}

function makeSeries(): SeriesOption[] {
  const fnv = flightEnvelope
  const prod = stdProcedure
  const xFn = getXFn()
  const yFn = fromMeterConverter(altUnit.value)
  return [
    {
      type: 'line',
      name: 'minCAS',
      showSymbol: false,
      data: fnv.minCAS.map((e) => [xFn(e), yFn(e.alt)])
    },
    {
      type: 'line',
      name: 'maxAlt',
      showSymbol: false,
      data: fnv.maxAlt.map((e) => [xFn(e), yFn(e.alt)])
    },
    {
      type: 'line',
      name: 'maxCAS',
      showSymbol: false,
      data: fnv.maxCAS.map((e) => [xFn(e), yFn(e.alt)])
    },
    {
      type: 'line',
      name: 'maxMach',
      showSymbol: false,
      data: fnv.maxMach.map((e) => [xFn(e), yFn(e.alt)])
    },
    {
      type: 'line',
      name: '标准程序',
      showSymbol: false,
      data: prod.line.map((e) => [xFn(e), yFn(e.alt)])
    }
  ]
}

function getXFn(): (e: FlightEnvelopeItem) => number {
  if (spdType.value === SpeedType.Mach) {
    return (e) => Math.round(e.mach * 100.0) / 100.0
  } else {
    const fn1 = fromMpsConvert(spdUnit.value)
    if (spdType.value === SpeedType.CAS) {
      return (e) => Math.round(fn1(e.cas))
    }
    return (e) => Math.round(fn1(e.tas))
  }
}

function updateAll() {
  updateFlightEnvelope()
  updateStdProcedure()
  updateChart()
}

onMounted(() => {
  chart = initEChart(chartEl.value)
  updateAll()
})
onUnmounted(() => {
  chart?.dispose()
})

watch(acType, () => updateAll())
watch(altUnit, () => updateChart())
watch(spdType, () => updateChart())
watch(spdUnit, () => updateChart())
</script>
<template>
  <div class="bada-envelope pane-block">
    <div class="row">
      <div class="txt-box col-3em">机型</div>
      <BADAAircraftTypeSelect v-model="acType" />
      <div style="margin-left: 1.5em; width: 1.5em" class="border-left" />
      <div class="txt-box" style="margin-right: 1em">速度类型</div>
      <SpeedTypeSelect v-model="spdType" style="margin-right: 2em" />
      <div class="txt-box" style="margin-right: 1em">速度单位</div>
      <SpeedUnitSelect
        v-model="spdUnit"
        :options="[SpeedUnit.MPS, SpeedUnit.KMPH, SpeedUnit.KT]"
        style="margin-right: 2em"
      />
      <div class="txt-box" style="margin-right: 1em">高度单位</div>
      <LengthUnitSelect v-model="altUnit" :options="[LengthUnit.M, LengthUnit.FT]" />
    </div>
    <hr class="border-bottom" style="margin: 0.5em 0" />
    <div class="cfe-chart" ref="chartEl"></div>
  </div>
</template>
<style lang="scss">
.bada-envelope {
  .cfe-chart {
    width: 70em;
    height: 30em;
  }
}
</style>
